#include "cuImage.h"

#include <iostream>
void cuImage::Init()
{
	ilInit();
	iluInit();
	ilutInit();
}

ILboolean cuImage::Load(char const * filename)
{
	m_il = ilGenImage();
	ilBindImage(m_il);

	ILboolean result = ilLoadImage(filename);
	if (result)
	{
		uint32 w = ilGetInteger(IL_IMAGE_WIDTH);
		uint32 h = ilGetInteger(IL_IMAGE_HEIGHT);
		uint32 bpp = ilGetInteger(IL_IMAGE_BITS_PER_PIXEL);
		uint32 type = ilGetInteger(IL_IMAGE_FORMAT);

		m_data.Create(BUFFER_H, w, h);

		uint32 p = m_data.whd().x;

		uchar4 * pDst = m_data.hPtr();

		if (bpp == 8)
		{
			uchar3 * pSrc = (uchar3 *) ilGetData();
			for (uint32 ir = 0; ir < h; ir++)
				for (uint32 ic = 0; ic < w; ic++)
				{
					pDst[ic + ir * p] = uc4(pSrc[ic + ir * w]);
				}
		}

		if (bpp == 24)
		{
			uchar3 * pSrc = (uchar3 *) ilGetData();
			for (uint32 ir = 0; ir < h; ir++)
				for (uint32 ic = 0; ic < w; ic++)
				{
					uchar3 color = pSrc[ic + ir * w];

					if (type == IL_RGB)
						pDst[ic + ir * p] = uc4(color);

					if (type == IL_BGR)
						pDst[ic + ir * p] = uc4(color.z, color.y, color.x, 255);
				}
		}

		if (bpp == 32)
		{
			uchar4 * pSrc = (uchar4 *) ilGetData();
			for (uint32 ir = 0; ir < h; ir++)
				for (uint32 ic = 0; ic < w; ic++)
				{
					uchar4 color = pSrc[ic + ir * w];

					if (type == IL_RGBA)
						pDst[ic + ir * p] = color;

					if (type == IL_BGRA)
						pDst[ic + ir * p] = uc4(color.z, color.y, color.x, color.w);
				}
		}
	}
	else
	{
		std::cerr << iluErrorString( ilGetError() ) << std::endl;
	}	

	ilDeleteImage(m_il); // free il resources

	return result;
}

ILboolean cuImage::Save(char const * filename)
{
	m_il = ilGenImage();
	ilBindImage(m_il);

	uint3 dim = m_data.dim();

	ilTexImage(dim.x, dim.y, dim.z, 4, IL_RGBA, IL_UNSIGNED_BYTE, NULL);

	uchar4 * pSrc = (uchar4 *) ilGetData();
	
	uint32 w = ilGetInteger(IL_IMAGE_WIDTH);	
	uint32 h = ilGetInteger(IL_IMAGE_HEIGHT);
	
	uint32 p = m_data.whd().x;

	uchar4 * pDst = m_data.hPtr();

	for (uint32 ir = 0; ir < h; ir++)
		for (uint32 ic = 0; ic < w; ic++)
		{
			// h-1-ir because the image is upside down
			//pSrc[ic + (h-1-ir) * w] = pDst[ic + ir * p];
			pSrc[ic + ir * w] = pDst[ic + ir * p];
		}

	ILboolean result = ilSaveImage(filename);

	ilDeleteImage(m_il); // free il resources

	if (!result) std::cerr << iluErrorString( ilGetError() ) << std::endl;

	return result;
}